package com.starblink.android.basic.base

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.apollographql.apollo3.api.Mutation
import com.apollographql.apollo3.api.Query
import com.starblink.android.basic.bean.LoadAction
import com.starblink.android.basic.network.base.SkGqlClient
import com.starblink.basic.util.ActivityStackManage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

open class BaseViewModel: ViewModel() {

    companion object {
        internal const val POP_OWNER = -1
    }

    internal val viewBaseLD: MutableLiveData<Int> = MutableLiveData<Int>(0)

    fun popSelfOwner() {
        viewBaseLD.postValue(POP_OWNER)
        ActivityStackManage.getActivityStack().pop()
    }

    var mLoadActionLiveData: MutableLiveData<LoadAction> = MutableLiveData()

    fun launchOnUI(block: suspend CoroutineScope.() -> Unit) {
        viewModelScope.launch {
            block.invoke(this)
        }
    }

    suspend fun <T> launchOnIO(block: suspend CoroutineScope.() -> T): T {
        return withContext(Dispatchers.IO) {
            block.invoke(this)
        }
    }

    /**
     * 设置并发射加载状态
     */
    fun setStateLiveData(loadState: LoadAction) {
        mLoadActionLiveData.postValue(loadState)
    }

    fun loadStartLoading() {
        mLoadActionLiveData.postValue(LoadAction(LoadAction.STATE_LOADING))
    }

    fun loadSuccess() {
        mLoadActionLiveData.postValue(LoadAction(LoadAction.STATE_SUCCESS))
    }

    fun loadError() {
        mLoadActionLiveData.postValue(LoadAction(LoadAction.STATE_ERROR))
    }

    fun loadError(message: String?) {
        loadError(-1, message)
    }

    fun loadError(errorCode: Int) {
        loadError(errorCode, null)
    }

    fun loadError(errorCode: Int, message: String?) {
        mLoadActionLiveData.postValue(LoadAction(LoadAction.STATE_ERROR, message = message, errorCode = errorCode))
    }

    fun loadNoData() {
        mLoadActionLiveData.postValue(LoadAction(LoadAction.STATE_NO_DATA))
    }

    fun loadStartProgress() {
        mLoadActionLiveData.postValue(LoadAction(LoadAction.STATE_PROGRESS))
    }

    fun loadHideProgress() {
        mLoadActionLiveData.postValue(LoadAction(LoadAction.STATE_HIDE_PROGRESS))
    }

    fun showLoadDialog() {
        viewModelScope.launch {
            mLoadActionLiveData.value = LoadAction(LoadAction.STATE_PROGRESS)
        }
    }

    fun hideLoadDialog() {
        viewModelScope.launch {
            mLoadActionLiveData.value = LoadAction(LoadAction.STATE_HIDE_PROGRESS)
        }
    }

    fun getActionLiveData(): MutableLiveData<LoadAction> {
        return mLoadActionLiveData
    }

    suspend fun <D : Query.Data> graphQLQuery(query: Query<D>, showLoading: Boolean = false) =
        SkGqlClient.skQuery(query, showDefaultLoading = showLoading)

    suspend fun <D : Mutation.Data> graphQLMutation(mutation: Mutation<D>, showLoading: Boolean = false) =
        SkGqlClient.skMutation(mutation, showDefaultLoading = showLoading)

}